﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Text;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Diagnostics;
using System.Windows.Forms;
using System.IO;
using System.Xml;
using System.Windows.Forms.Design;
using System.Runtime.Serialization;
using System.Runtime.InteropServices;
using System.Reflection;
using Excel = Microsoft.Office.Interop.Excel;
using USBHIDDRIVER;
using System.Drawing.Drawing2D;

// TODO Work more on the integrator part of software, so on the post-math stuff. For example by adding other data post-processing environments, such as electric power calculations, resistivity calculation, conductivity etc. The list is long!!!
// TODO Need to make the expression string parser more flexible and less susceptible to error (PRIORITARY)
// TODO Speed up and tidy up the code. Create common functions and classes for data processing. - ALMOST DONE

namespace VoltcraftControlInterface
{
    public partial class MainForm : Form
    {
        ToolTip err;
        SerialPort VoltPort;
        USBHIDDRIVER.USBInterface usb;
        Stopwatch logger;
        //Stopwatch logger2;
        Parser prs;
        bool istimeout;
        int lograte;
        executeMath mathparser;
        bool log1running, log2running;
        Dictionary<string, MemoryStream> logchartStreams;
        Dictionary<string, MemoryStream> dmmchartStreams;
        Dictionary<string, MemoryStream> heatchartStreams;
        Dictionary<string, MemoryStream> powchartStreams;
        Dictionary<string, string> mediumselected;
        AppSettings Settings;
        string startname;
        public string argument;
        public string fileopened;
        VoltageLooper CVL;

        //FONT EMBEDDING
        [DllImport("gdi32.dll")]
        private static extern IntPtr AddFontMemResourceEx(IntPtr pbFont, uint cbFont,
            IntPtr pdv, [In] ref uint pcFonts);
        private static PrivateFontCollection digifont;
        private static PrivateFontCollection digifontBold;

        Font DIGIfont975;
        Font DIGIfont12;
        Font DIGIfont36;
        Font DIGIfontBold1425;
        Font DIGIfontBold24;
        Font DIGIfontBold36;

        Thread updthread;
        Thread autosavethread;

        public MainForm()
        {
            InitializeComponent();
            ToolStripManager.Renderer = new ToolStripProfessionalRenderer(new CustomProfessionalColors());
            //DoubleBuffered = true;
            //SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
            this.ResizeBegin += (s, e) => { this.SuspendLayout(); };
            this.ResizeEnd += (s, e) => { this.ResumeLayout(true); };

            //INITIALIZING FONTS
            digifont = new PrivateFontCollection();
            digifontBold = new PrivateFontCollection();
            byte[] fontData = Properties.Resources.DS_DIGI;
            IntPtr fontPtr = Marshal.AllocCoTaskMem(fontData.Length);
            Marshal.Copy(fontData, 0, fontPtr, fontData.Length);
            uint dummy = 0;
            digifont.AddMemoryFont(fontPtr, Properties.Resources.DS_DIGI.Length);
            AddFontMemResourceEx(fontPtr, (uint)Properties.Resources.DS_DIGI.Length, IntPtr.Zero, ref dummy);
            Marshal.FreeCoTaskMem(fontPtr);
            DIGIfont975 = new Font(digifont.Families[0], 9.75F);
            DIGIfont12 = new Font(digifont.Families[0], 12.0F);
            DIGIfont36 = new Font(digifont.Families[0], 36.0F);

            byte[] fontBData = Properties.Resources.DS_DIGIB;
            IntPtr fontBPtr = Marshal.AllocCoTaskMem(fontBData.Length);
            Marshal.Copy(fontBData, 0, fontBPtr, fontBData.Length);
            dummy = 0;
            digifontBold.AddMemoryFont(fontBPtr, Properties.Resources.DS_DIGIB.Length);
            AddFontMemResourceEx(fontBPtr, (uint)Properties.Resources.DS_DIGIB.Length, IntPtr.Zero, ref dummy);
            Marshal.FreeCoTaskMem(fontBPtr);
            DIGIfontBold1425 = new Font(digifontBold.Families[0], 14.25F, FontStyle.Bold);
            DIGIfontBold24 = new Font(digifontBold.Families[0], 24.0F, FontStyle.Bold);
            DIGIfontBold36 = new Font(digifontBold.Families[0], 36.0F, FontStyle.Bold);

            fileopened = "";

            shouldlogpower = false;
            log1running = log2running = false;
            mathparser = new executeMath();
            prs = new Parser();
            logger = new Stopwatch();
            SerialPort ComPort = new SerialPort();
            string[] ArrayComPortsNames = null;
            int index = -1;
            string ComPortName = null;
            ArrayComPortsNames = SerialPort.GetPortNames();
            if (ArrayComPortsNames.Length > 0)
            {
                do
                {
                    index += 1;
                    tscomList.Items.Add((ArrayComPortsNames[index]));
                }
                while (!((ArrayComPortsNames[index] == ComPortName) ||
                                    (index == ArrayComPortsNames.GetUpperBound(0))));
                if (index == ArrayComPortsNames.GetUpperBound(0))
                {
                    ComPortName = ArrayComPortsNames[0];
                }
                tscomList.Text = ArrayComPortsNames[0];
            } else
            {
                tsselectBtn.Enabled = false;
                tscomList.Enabled = false;
            }
            USBInterface usbl = new USBInterface("vid_1244");
            String[] list = usbl.getDeviceList();
            if(list.Length==0)
            {
                tsdmmList.Enabled = false;
                tsstartmultimBtn.Enabled = false;
            } else
            {
                for (int i = 0; i < list.Length; i++)
                {
                    tsdmmList.Items.Add(list[i]);
                }
                tsdmmList.SelectedIndex = 0;
            }
            info = new ToolTip();
            err = new ToolTip();
            shouldlogHeat = false;
            poli = new PolynomialIntegrator();
            listofmediums = new DataTable();
            listofmediums.Clear();
            listofmediums.Columns.Add("Name");
            listofmediums.Columns.Add("Expression");
            string appdataDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "InstruMan\\");
            if (!Directory.Exists(appdataDir)) Directory.CreateDirectory(appdataDir);
            if (!File.Exists(Path.Combine(appdataDir, "settings.xml")))
            {
                XmlDocument newdoc = new XmlDocument();
                XmlDeclaration xmlDeclaration = newdoc.CreateXmlDeclaration("1.0", "UTF-8", null);
                XmlElement root = newdoc.DocumentElement;
                newdoc.InsertBefore(xmlDeclaration, root);
                XmlElement xmlroot = newdoc.CreateElement(string.Empty, "Materials", string.Empty);
                newdoc.AppendChild(xmlroot);

                XmlElement airentry = newdoc.CreateElement(string.Empty, "Entry", string.Empty);
                airentry.SetAttribute("name", "Air");
                airentry.SetAttribute("expression", "-4,91e-11x^4+7,659e-8x^3-4,369e-5x^2+1,089e-2x^1+4,161e-6");
                xmlroot.AppendChild(airentry);

                XmlElement waterentry = newdoc.CreateElement(string.Empty, "Entry", string.Empty);
                waterentry.SetAttribute("name", "Water");
                waterentry.SetAttribute("expression", "-7,617e-10x^4+9,0322e-7x^3-3,841e-4x^2+6,844e-2x^1+1,297e-6");
                xmlroot.AppendChild(waterentry);
                try
                {
                    newdoc.Save(Path.Combine(appdataDir, "settings.xml"));
                }
                catch (UnauthorizedAccessException)
                {
                    MessageBox.Show("Settings file corrupted or deleted! Restart application with Administrator privileges to repair", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    Application.Exit();
                }
            }
            try
            {
                XmlDocument settings = new XmlDocument();
                settings.Load(Path.Combine(appdataDir, "settings.xml"));
                if (settings.HasChildNodes)
                {
                    XmlNode rootnode = settings.SelectSingleNode("Materials");
                    if (rootnode.HasChildNodes)
                    {
                        XmlNodeList entries = rootnode.SelectNodes("Entry");

                        string name = "";
                        string expression = "";
                        for (int i = 0; i < entries.Count; i++)
                        {
                            name = entries[i].Attributes["name"].Value;
                            expression = entries[i].Attributes["expression"].Value;
                            if ((name != "") && (expression != ""))
                            {
                                DataRow newrow = listofmediums.NewRow();
                                newrow["Name"] = name;
                                newrow["Expression"] = expression;
                                listofmediums.Rows.Add(newrow);
                                mediumList.Items.Add(name);
                            }
                        }
                        mediumList.SelectedIndex = 0;
                    }
                    else throw new System.ArgumentException("XML file does not contain values to initiate settings");
                }
                else throw new System.ArgumentException("Bad XML file");
            }
            catch
            {
                /*MessageBox.Show("Bad XML settings file! Delete it manually and restart application!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Environment.FailFast("Error while loading XML settings file"+Environment.NewLine+e);*/
                File.Delete(Path.Combine(appdataDir, "settings.xml"));
                XmlDocument newdoc = new XmlDocument();
                XmlDeclaration xmlDeclaration = newdoc.CreateXmlDeclaration("1.0", "UTF-8", null);
                XmlElement root = newdoc.DocumentElement;
                newdoc.InsertBefore(xmlDeclaration, root);
                XmlElement xmlroot = newdoc.CreateElement(string.Empty, "Materials", string.Empty);
                newdoc.AppendChild(xmlroot);

                XmlElement airentry = newdoc.CreateElement(string.Empty, "Entry", string.Empty);
                airentry.SetAttribute("name", "Air");
                airentry.SetAttribute("expression", "-4,91e-11x^4+7,659e-8x^3-4,369e-5x^2+1,089e-2x^1+4,161e-6");
                xmlroot.AppendChild(airentry);

                XmlElement waterentry = newdoc.CreateElement(string.Empty, "Entry", string.Empty);
                waterentry.SetAttribute("name", "Water");
                waterentry.SetAttribute("expression", "-7,617e-10x^4+9,0322e-7x^3-3,841e-4x^2+6,844e-2x^1+1,297e-6");
                xmlroot.AppendChild(waterentry);
                newdoc.Save(Path.Combine(appdataDir, "settings.xml"));
                try
                {
                    XmlDocument settings = new XmlDocument();
                    settings.Load(Path.Combine(appdataDir, "settings.xml"));
                    if (settings.HasChildNodes)
                    {
                        XmlNode rootnode = settings.SelectSingleNode("Materials");
                        if (rootnode.HasChildNodes)
                        {
                            XmlNodeList entries = rootnode.SelectNodes("Entry");

                            string name = "";
                            string expression = "";
                            for (int i = 0; i < entries.Count; i++)
                            {
                                name = entries[i].Attributes["name"].Value;
                                expression = entries[i].Attributes["expression"].Value;
                                if ((name != "") && (expression != ""))
                                {
                                    DataRow newrow = listofmediums.NewRow();
                                    newrow["Name"] = name;
                                    newrow["Expression"] = expression;
                                    listofmediums.Rows.Add(newrow);
                                    mediumList.Items.Add(name);
                                }
                            }
                            mediumList.SelectedIndex = 0;
                        }
                        else throw new System.ArgumentException("XML file does not contain values to initiate settings");
                    }
                    else throw new System.ArgumentException("Bad XML file");
                }
                catch (System.Exception e)
                {
                    MessageBox.Show("Bad XML settings file! Delete it manually and restart application!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    Environment.FailFast("Error while loading XML settings file" + Environment.NewLine + e);
                }
            }
            if(File.Exists(Path.Combine(appdataDir,"preferences.ims")))
            {
                //IFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                System.Xml.Serialization.XmlSerializer formatter = new System.Xml.Serialization.XmlSerializer(typeof(AppSettings));
                Stream stream = new FileStream(Path.Combine(appdataDir, "preferences.ims"), FileMode.Open, FileAccess.Read, FileShare.Read);
                Settings = ((AppSettings)formatter.Deserialize(stream));
                stream.Close();
            } else
            {
                Settings = new AppSettings();
                Settings.AutoSave = true;
                Settings.currLimit = 0;
                Settings.EmergencyStop = true;
                Settings.ovCurrProtection = false;
                Settings.AutoSaveTimeout = 15000;
            }
            if(Settings.AutoSave)
            {
                autosavethread = new Thread(new ThreadStart(this.AutoSaveThread));
                autosavethread.Start();
                while (!autosavethread.IsAlive) ;
            }
        }

        public void LoadFile(string fpath)
        {
            SerializerClass serialparser = new SerializerClass();
            IFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
            Stream stream = new FileStream(fpath, FileMode.Open, FileAccess.Read, FileShare.Read);
            serialparser = (SerializerClass)formatter.Deserialize(stream);
            stream.Close();
            logChart.Series[0].Points.Clear();
            logChart.Series[1].Points.Clear();
            dmmChart.Series[0].Points.Clear();
            heatChart.Series[0].Points.Clear();
            heatChart.Series[1].Points.Clear();
            prjlistTree.Nodes.Clear();
            logchartStreams.Clear();
            dmmchartStreams.Clear();
            heatchartStreams.Clear();
            powchartStreams.Clear();
            logchartStreams = serialparser.logserialize;
            dmmchartStreams = serialparser.dmmserialize;
            heatchartStreams = serialparser.heatserialize;
            powchartStreams = serialparser.powserialize;

            listofmediums = serialparser.listofmediums;
            mediumselected = serialparser.mediumselected;
            mediumList.Items.Clear();
            foreach (DataRow row in listofmediums.Rows)
            {
                mediumList.Items.Add(row[0]);
            }
            mediumList.SelectedItem = serialparser.mediumselected;

            foreach (KeyValuePair<string, MemoryStream> entry in serialparser.logserialize)
            {
                prjlistTree.Nodes.Add(entry.Key);
            }
            if (prjlistTree.Nodes.Count > 0) prjlistTree.SelectedNode = prjlistTree.Nodes[0];
        }

        public void SaveFile(string fpath)
        {
            MemoryStream logsys = new MemoryStream();
            MemoryStream dmmsys = new MemoryStream();
            MemoryStream heatsys = new MemoryStream();
            MemoryStream powsys = new MemoryStream();
            logChart.Serializer.Save(logsys);
            dmmChart.Serializer.Save(dmmsys);
            heatChart.Serializer.Save(heatsys);
            powChart.Serializer.Save(powsys);
            if (prjlistTree.SelectedNode != null)
            {
                if (logchartStreams.ContainsKey(prjlistTree.SelectedNode.Text))
                {
                    logchartStreams.Remove(prjlistTree.SelectedNode.Text);
                }
                if (dmmchartStreams.ContainsKey(prjlistTree.SelectedNode.Text))
                {
                    dmmchartStreams.Remove(prjlistTree.SelectedNode.Text);
                }
                if (heatchartStreams.ContainsKey(prjlistTree.SelectedNode.Text))
                {
                    heatchartStreams.Remove(prjlistTree.SelectedNode.Text);
                }
                if (powchartStreams.ContainsKey(prjlistTree.SelectedNode.Text))
                {
                    powchartStreams.Remove(prjlistTree.SelectedNode.Text);
                }
                logchartStreams.Add(prjlistTree.SelectedNode.Text, logsys);
                dmmchartStreams.Add(prjlistTree.SelectedNode.Text, dmmsys);
                heatchartStreams.Add(prjlistTree.SelectedNode.Text, heatsys);
                powchartStreams.Add(prjlistTree.SelectedNode.Text, powsys);
            }
            SerializerClass serialparser = new SerializerClass();
            serialparser.logserialize = logchartStreams;
            serialparser.dmmserialize = dmmchartStreams;
            serialparser.heatserialize = heatchartStreams;
            serialparser.powserialize = powchartStreams;
            serialparser.listofmediums = listofmediums;
            serialparser.mediumselected = mediumselected;
            IFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); //BINARY FORMATTER OF SERIALIZATION - SUBSTITUTED WITRH XMLSERIALIZER
                                                                                                         //System.Xml.Serialization.XmlSerializer formatter = new System.Xml.Serialization.XmlSerializer(typeof(SerializerClass));
            Stream stream = new FileStream(fpath, FileMode.Create, FileAccess.Write, FileShare.None);
            formatter.Serialize(stream, serialparser);
            stream.Close();
        }

        string ReplaceFirst(string text, string search, string replace)
        {
            int pos = text.IndexOf(search);
            if (pos < 0)
            {
                return text;
            }
            return text.Substring(0, pos) + replace + text.Substring(pos + search.Length);
        }
        //DateTime starttime;
        public string WriteAndRead(string towrite)
        {
            int btoread = VoltPort.BytesToRead;
            string outstring = "";
            Byte[] waste=new Byte[btoread];
            VoltPort.Read(waste, 0, btoread);
            VoltPort.Write(towrite);
            Thread.Sleep(25);
            bool loopstat = true;
            int loopcount = 0;
            string appstring = "";
            while (loopstat)
            {
                btoread = VoltPort.BytesToRead;
                char[] returnbuff = new char[btoread];
                VoltPort.Read(returnbuff, 0, btoread);
                string retstring = new string(returnbuff);
                appstring = appstring + retstring;
                if (appstring.Contains("OK\r"))
                {
                    appstring = ReplaceFirst(appstring, "OK\r", "");
                    outstring = appstring;
                    loopstat = false;
                }
                if (retstring == "")
                {
                    loopcount++;
                }
                if (loopcount > 100)
                {
                    outstring = appstring;
                    loopstat = false;
                }
                if (loopstat) Thread.Sleep(2);
            }
            return outstring;
        }
        private void label1_Click(object sender, EventArgs e)
        {

        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e) //Open Connection Button
        {
            Double maxval = 0;
            if (logChart.Series[0].Points.Count > 0) maxval = logChart.Series[0].Points.Last().XValue;
            if ((logger.Elapsed.TotalSeconds+1) >= maxval)
            {
                tscomList.Enabled = false;
                tsselectBtn.Enabled = false;
                VoltPort = new SerialPort(tscomList.Text, 9600, Parity.None, 8, StopBits.One);
                VoltPort.Handshake = Handshake.None;
                VoltPort.WriteTimeout = 200;
                VoltPort.ReadTimeout = 200;
                try
                {
                    VoltPort.Open();
                    /*try
                    {
                        VoltPort.Write("GETS\r");
                    }
                    catch (System.Exception ex)
                    {
                        shouldstop = true;
                        MessageBox.Show("Error! " + ex, "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    System.Threading.Thread.Sleep(350);
                    char[] buff = new char[150];
                    try
                    {
                        if ((VoltPort != null) && (VoltPort.IsOpen)) VoltPort.Read(buff, 0, 150);
                    }
                    catch (System.Exception ex)
                    {
                        shouldstop = true;
                        MessageBox.Show("Error! " + ex, "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }*/
                    string bufs = "";
                    bufs = WriteAndRead("GETS\r");
                    string volt = bufs.Substring(0, 3);
                    string curr = bufs.Substring(3, 3);
                    Decimal vint = 0;
                    Decimal cint = 0;
                    try
                    {
                        vint = Decimal.Parse(volt);
                        cint = Decimal.Parse(curr);
                    }
                    catch
                    {

                    }
                    Decimal vDec = vint / 10;
                    Decimal cDec = cint / 10;
                    voltBox.Value = vDec;
                    currBox.Value = cDec;
                    //logChart.Series["Voltage"].Points.Clear();
                    //logChart.Series["Current"].Points.Clear();
                    lograte = (int)tsrateBox.Value;
                    updthread = new Thread(new ThreadStart(this.StartUpdating));
                    updthread.Start();
                    while (!updthread.IsAlive) ;
                    tscloseBtn.Enabled = true;
                    controlsPnl.Enabled = true;
                    tsrateBox.Enabled = false;
                    prjlistTree.Enabled = false;
                    toolStrip2.Enabled = false;
                    loadprjBtn.Enabled = false;
                    saveprjBtn.Enabled = false;
                    log1running = true;
                }
                catch (System.Exception ex)
                {
                    MessageBox.Show("Error while opening COM port! " + ex, "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    VoltPort.Close();
                    tscomList.Enabled = true;
                    tsselectBtn.Enabled = true;
                    tscloseBtn.Enabled = false;
                    this.StopUpdating();
                    System.Threading.Thread.Sleep(10);
                    //if (updthread.IsAlive) updthread.Abort();
                    controlsPnl.Enabled = false;
                    tsrateBox.Enabled = true;
                    log1running = false;
                    if (!log2running)
                    {
                        prjlistTree.Enabled = true;
                        toolStrip2.Enabled = true;
                        loadprjBtn.Enabled = true;
                        saveprjBtn.Enabled = true;
                    }
                }
            }
            else
            {
                MessageBox.Show("Can't overwrite old chart data! First clear the chart or create a new experiment using the left toolbox", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }

        private void closeBtn_Click(object sender, EventArgs e)
        {
            this.StopUpdating();
            System.Threading.Thread.Sleep(100);
            VoltPort.Close();
            //VoltPort.Dispose();
            //VoltPort = null;
            tscloseBtn.Enabled = false;
            tsselectBtn.Enabled = true;
            tscomList.Enabled = true;
            //if (updthread.IsAlive) updthread.Abort();
            controlsPnl.Enabled = false;
            tsrateBox.Enabled = true;
            log1running = false;
        }

        private void label2_Click(object sender, EventArgs e)
        {

        }

        private void button1_Click_1(object sender, EventArgs e)
        {
            try
            {
                istimeout = true;
                Thread.Sleep(100);
                WriteAndRead("SOUT0\r");
                Thread.Sleep(50);
                istimeout = false;
            }
            catch
            {
                MessageBox.Show("Error while turning ON instrument!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void offBtn_Click(object sender, EventArgs e)
        {
            try
            {
                istimeout = true;
                Thread.Sleep(100);
                WriteAndRead("SOUT1\r");
                Thread.Sleep(50);
                istimeout = false;
            }
            catch
            {
                MessageBox.Show("Error while turning OFF instrument!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void setvcBtn_Click(object sender, EventArgs e)
        {
            Decimal volt = voltBox.Value;
            volt = volt * 10;
            try
            {
                istimeout = true;
                Thread.Sleep(50);
                if (volt<10)
                            {
                                WriteAndRead("VOLT00" + volt.ToString("F0") + "\r");
                            } else if (volt<100) 
                            {
                                WriteAndRead("VOLT0" + volt.ToString("F0") + "\r");
                            } else
                            {
                                WriteAndRead("VOLT" + volt.ToString("F0") + "\r");
                            }
                Thread.Sleep(50);
                istimeout = false;
            }
            catch
            {
                MessageBox.Show("Error setting voltage!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void setcurrBtn_Click(object sender, EventArgs e)
        {
            istimeout = true;
            Decimal curr = currBox.Value;
            curr = curr * 10;
            try
            {
                istimeout = true;
                Thread.Sleep(50);
                if (curr < 10)
                {
                    WriteAndRead("CURR00" + curr.ToString("F0") + "\r");
                }
                else if (curr < 100)
                {
                    WriteAndRead("CURR0" + curr.ToString("F0") + "\r");
                }
                else
                {
                    WriteAndRead("CURR" + curr.ToString("F0") + "\r");
                }
                Thread.Sleep(50);
                istimeout = false;
            }
            catch
            {
                MessageBox.Show("Error setting current!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        public void disableOpen()
        {
            this.tsselectBtn.Enabled = false;
        }
        public void enableOpen()
        {
            this.tsselectBtn.Enabled = true;
        }
        public bool IsOpen()
        {
            return !tsselectBtn.Enabled;
        }
        //DateTime nowtime;
        TimeSpan elapsed;
        delegate void SetTextCallback(Decimal voltage, Decimal current);
        private void SetText(Decimal voltage, Decimal current)
        {
            // InvokeRequired required compares the thread ID of the
            // calling thread to the thread ID of the creating thread.
            // If these threads are different, it returns true.
            if (this.voltLbl.InvokeRequired)
            {
                SetTextCallback d = new SetTextCallback(SetText);
                Invoke(d, new object[] { voltage, current });
            }
            else
            {
                this.voltLbl.Text = voltage.ToString("F1") + " V";
                this.currLbl.Text = current.ToString("F1") + " A";
                //nowtime = DateTime.Now;
                elapsed = logger.Elapsed;
                Double now = DateTime.Now.ToOADate();
                Double elapsd;
                elapsd = elapsed.TotalSeconds;
                this.logChart.Series["Voltage"].Points.AddXY(elapsd, voltage, now);
                this.logChart.Series["Current"].Points.AddXY(elapsd, current, now);
                //power tab updating
                if (logChart.Series[0].Points.Count > 1)
                {
                    Double lv = logChart.Series["Voltage"].Points[logChart.Series[0].Points.Count - 1].YValues[0];
                    Double slv = logChart.Series["Voltage"].Points[logChart.Series[0].Points.Count - 2].YValues[0];
                    Double lc = logChart.Series["Current"].Points[logChart.Series[0].Points.Count - 1].YValues[0];
                    Double slc = logChart.Series["Current"].Points[logChart.Series[0].Points.Count - 2].YValues[0];
                    Double time = logChart.Series[0].Points[logChart.Series[0].Points.Count - 1].XValue;
                    Double stime = logChart.Series[0].Points[logChart.Series[0].Points.Count - 2].XValue;
                    SetPower(lv, slv, lc, slc, time, stime, elapsd, now);
                }
            }
        }
        public void StartUpdating()
        {
            shouldstop = false;
            istimeout = false;
            //starttime = DateTime.Now;
            //nowtime = new DateTime();
            bool numerror;
            if(!logger.IsRunning) logger.Start();
            while (!shouldstop)
            {
                numerror = false;
                if (!istimeout)
                {
                    /*try
                    {
                        VoltPort.Write("GETD\r");
                    }
                    catch (System.Exception ex)
                    {
                        shouldstop = true;
                        MessageBox.Show("Error! " + ex, "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    System.Threading.Thread.Sleep(50);
                    char[] buff = new char[15];
                    try
                    {
                        VoltPort.Read(buff, 0, 15);
                    }
                    catch (System.Exception ex)
                    {
                        shouldstop = true;
                        MessageBox.Show("Error while logging data! " + ex, "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }*/
                    string bufs = "";
                    try
                    {
                        bufs = WriteAndRead("GETD\r");
                    }
                    catch (System.Exception ex)
                    {
                        MessageBox.Show("Error! " + ex, "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        shouldstop = true;
                    }
                    if (bufs.Length >= 7)
                    {
                        string volt = bufs.Substring(0, 3);
                        string curr = bufs.Substring(4, 3);
                        Decimal vint = 0;
                        Decimal cint = 0;
                        try
                        {
                            vint = Decimal.Parse(volt);
                            cint = Decimal.Parse(curr);
                        }
                        catch
                        {
                            numerror = true;
                        }
                        Decimal vDec = vint / 10;
                        Decimal cDec = cint / 10;
                        if(!numerror) SetText(vDec, cDec);
                    }
                    System.Threading.Thread.Sleep(lograte - 50);
                } else Thread.Sleep(100);
            }
            if (!log2running)
            {
                logger.Stop();
                ReEnable();
            }
            log1running = false;
        }
        public delegate void ReEnableDel();
        public void ReEnable()
        {
            if (this.prjlistTree.InvokeRequired)
            {
                ReEnableDel d = new ReEnableDel(ReEnable);
                Invoke(d, new object[] { });
            }
            else
            {
                prjlistTree.Enabled = true;
                toolStrip2.Enabled = true;
                loadprjBtn.Enabled = true;
                saveprjBtn.Enabled = true;
            }
        }

        public void StopUpdating()
        {
            shouldstop = true;
        }
        private volatile bool shouldstop;
        private volatile bool shouldstopautosave;

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (VoltPort != null)
            {
                VoltPort.Close();
                VoltPort.Dispose();
            }
            this.StopUpdating();
            System.Threading.Thread.Sleep(10);
            if (updthread!=null)
             if (updthread.IsAlive) updthread.Abort();
            if (usb != null)
            {
                usb.stopRead();
                usb.Disconnect();
            }
            if (autosavethread != null)
                if (autosavethread.IsAlive)
                {
                    shouldstopautosave = true;
                    autosavethread.Abort();
                }
            string appdataDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "InstruMan\\");
            if (File.Exists(Path.Combine(appdataDir, "settings.xml"))) File.Delete(Path.Combine(appdataDir, "settings.xml"));
            XmlDocument newdoc = new XmlDocument();
            XmlDeclaration xmlDeclaration = newdoc.CreateXmlDeclaration("1.0", "UTF-8", null);
            XmlElement root = newdoc.DocumentElement;
            newdoc.InsertBefore(xmlDeclaration, root);
            XmlElement xmlroot = newdoc.CreateElement(string.Empty, "Materials", string.Empty);
            newdoc.AppendChild(xmlroot);
            DataRow[] resultrow = listofmediums.Select();
            XmlElement[] newentry = new XmlElement[resultrow.Length];
            int count = 0;
            foreach (DataRow row in resultrow)
            {
                newentry[count] = newdoc.CreateElement(string.Empty, "Entry", string.Empty);
                newentry[count].SetAttribute("name", row["Name"].ToString());
                newentry[count].SetAttribute("expression", row["Expression"].ToString());
                xmlroot.AppendChild(newentry[count]);
                count++;
            }
            newdoc.Save(Path.Combine(appdataDir, "settings.xml"));

            if (File.Exists(Path.Combine(appdataDir, "preferences.ims"))) File.Delete(Path.Combine(appdataDir, "preferences.ims"));
            //IFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); //BINARY FORMATTER OF SERIALIZATION - SUBSTITUTED WITRH XMLSERIALIZER
            System.Xml.Serialization.XmlSerializer formatter = new System.Xml.Serialization.XmlSerializer(typeof(AppSettings));
            Stream stream = new FileStream(Path.Combine(appdataDir, "preferences.ims"), FileMode.Create, FileAccess.Write, FileShare.None);
            formatter.Serialize(stream, Settings);
            stream.Close();

            if (Settings.AutoSave) AutoSave();
        }

        private void chart1_Click(object sender, EventArgs e)
        {

        }

        private void savelogBtn_Click(object sender, EventArgs e)
        {
            SaveFileDialog filepath = new SaveFileDialog();
            filepath.Filter = "CSV Spreadsheet|*.csv";
            filepath.Title = "Save Logged Data";
            filepath.ShowDialog();
            if (filepath.FileName != "")
            {
                if (System.IO.File.Exists(filepath.FileName)) System.IO.File.Delete(filepath.FileName);
                using (System.IO.StreamWriter file =
              new System.IO.StreamWriter(@filepath.FileName, true))
                {
                    string line = "";
                    bool log = false, dmm = false;
                    if (logChart.Series[0].Points.Count > 0)
                    {
                        log = true;
                    }
                    if(dmmChart.Series[0].Points.Count>0)
                    {
                        dmm = true;
                    }
                    if(log&&!dmm)
                    {
                        line = "Time(s);Time;Voltage;Current";
                        file.WriteLine(line);
                        for (int i = 0; i < logChart.Series["Voltage"].Points.Count; i++)
                        { 
                            //parsetime = DateTime.FromOADate(logChart.Series["Voltage"].Points[i].XValue);
                            file.WriteLine(logChart.Series["Voltage"].Points[i].XValue + ";"+ DateTime.FromOADate(logChart.Series["Voltage"].Points[i].YValues[1]).ToLongTimeString()+"."+ DateTime.FromOADate(logChart.Series["Voltage"].Points[i].YValues[1]).Millisecond + ";" + logChart.Series["Voltage"].Points[i].YValues[0].ToString("F1") + ";" + logChart.Series["Current"].Points[i].YValues[0].ToString("F1"));
                        }
                    }
                    if(!log&&dmm)
                    {
                        line = "Time(s);Time;" + dmmChart.ChartAreas[0].AxisY.Title;
                        file.WriteLine(line);
                        for (int i = 0; i < dmmChart.Series[0].Points.Count; i++)
                        {
                            file.WriteLine(dmmChart.Series[0].Points[i].XValue + ";" + DateTime.FromOADate(dmmChart.Series[0].Points[i].YValues[1]).ToLongTimeString()+ "."+DateTime.FromOADate(dmmChart.Series[0].Points[i].YValues[1]).Millisecond + ";" + dmmChart.Series[0].Points[i].YValues[0].ToString());
                        }
                    }
                    if (log&&dmm)
                    {
                        line = "Time(s);Time;Voltage;Current;;"+ "Time(s);Time;" + dmmChart.ChartAreas[0].AxisY.Title;
                        file.WriteLine(line);
                        int max;
                        if (logChart.Series["Voltage"].Points.Count > dmmChart.Series[0].Points.Count)
                            max = logChart.Series["Voltage"].Points.Count;
                        else max = dmmChart.Series[0].Points.Count;
                        for (int i = 0; i < max; i++)
                        {
                            if (i < logChart.Series["Voltage"].Points.Count)
                                file.Write(logChart.Series["Voltage"].Points[i].XValue + ";"+ DateTime.FromOADate(logChart.Series["Voltage"].Points[i].YValues[1]).ToLongTimeString()+"."+ DateTime.FromOADate(logChart.Series["Voltage"].Points[i].YValues[1]).Millisecond + ";" + logChart.Series["Voltage"].Points[i].YValues[0].ToString("F1") + ";" + logChart.Series["Current"].Points[i].YValues[0].ToString("F1"));
                            else file.Write(";;;");
                            if (i< dmmChart.Series[0].Points.Count) file.Write(";;"+dmmChart.Series[0].Points[i].XValue + ";" + DateTime.FromOADate(dmmChart.Series[0].Points[i].YValues[1]).ToLongTimeString()+"."+ DateTime.FromOADate(dmmChart.Series[0].Points[i].YValues[1]).Millisecond + ";" + dmmChart.Series[0].Points[i].YValues[0].ToString());
                            file.Write(Environment.NewLine);
                        }
                    }
                    file.Close();

                }
            }
        }

        private void numericUpDown1_ValueChanged(object sender, EventArgs e)
        {

        }

        private void closeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void openSToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.StopUpdating();
            System.Threading.Thread.Sleep(100);
            if((VoltPort!=null)&&(VoltPort.IsOpen)) VoltPort.Close();
            //VoltPort.Dispose();
            //VoltPort = null;
            tscloseBtn.Enabled = false;
            tsselectBtn.Enabled = true;
            tscomList.Enabled = true;
            //if (updthread.IsAlive) updthread.Abort();
            controlsPnl.Enabled = false;
            tsrateBox.Enabled = true;
            CVL = new VoltageLooper(this);
            CVL.Show();
            /*using (Form2 CVL = new Form2())
            {
                CVL.ShowDialog(this);
            }*/
        }

        private void fileToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {using (AboutBox1 about = new AboutBox1())
            {
                about.ShowDialog(this);
            }

        }
        public void LogDMM(object sender, EventArgs e)
        {
            if (USBInterface.usbBuffer.Count>0)
            {
                Byte[] dataRecord = null;
                int counter = 0;
                while ((byte[])USBHIDDRIVER.USBInterface.usbBuffer[counter] == null)
                {
                    //Remove this report from list
                    lock (USBHIDDRIVER.USBInterface.usbBuffer.SyncRoot)
                    {
                        USBHIDDRIVER.USBInterface.usbBuffer.RemoveAt(0);
                    }
                }
                //since the remove statement at the end of the loop take the first element
                dataRecord = (Byte[])USBHIDDRIVER.USBInterface.usbBuffer[0];
                lock (USBHIDDRIVER.USBInterface.usbBuffer.SyncRoot)
                {
                    USBHIDDRIVER.USBInterface.usbBuffer.RemoveAt(0);
                }
                /*string data = "";
                for (int i = 0; i < dataRecord.Length; i++)
                {
                    data = data + dataRecord[i].ToString()+" ";
                }
                MessageBox.Show(data);*/
                /*string passphrase = "jodenxunickxia";
                byte[] asciiPass = Encoding.ASCII.GetBytes(passphrase);
                for (int i = 0; i < 14; i++)
                {
                    dataRecord[i + 1] -= asciiPass[i];
                }*/
                //string data = "";
                //char[] recChar = Encoding.ASCII.GetChars(dataRecord);
                //bytes read have a 0 byte at initial position, so we swap all indexes by 1
                double elapsed = logger.Elapsed.TotalSeconds;
                double now = DateTime.Now.ToOADate();
                if (!((dataRecord[1] == 0) && (dataRecord[2] == 0) && (dataRecord[3] == 0)))
                {
                    prs.inputBytes = dataRecord;
                    prs.UpdateResult();
                    if(!prs.IsOutOfRange) SetDmmChart(prs.RectifiedValue, elapsed, now);
                    if ((prs.UnitOfMeasure == "A") || (prs.UnitOfMeasure == "V"))
                    {
                        acLbl.ForeColor = prs.IsAC ? Color.Red : Color.Gray;
                        dcLbl.ForeColor = prs.IsDC ? Color.Red : Color.Gray;
                    }
                    autoLbl.ForeColor = prs.IsAutoSub ? Color.Red : Color.Gray;
                    holdLbl.ForeColor = prs.IsHold ? Color.Red : Color.Gray;
                    if (prs.IsOutOfRange)
                    {
                        SetLabel("Out of range!");
                    }
                    else
                    {
                        SetLabel(prs.Value);
                    }
                    SetTitle(prs.LongUnitOfMeasure);
                    maxLbl.ForeColor = prs.IsMax ? Color.Red : Color.Gray;
                    minLbl.ForeColor = prs.IsMin ? Color.Red : Color.Gray;
                    relLbl.ForeColor = prs.IsRel ? Color.Red : Color.Gray;
                    if (prs.IsAC) SetTitle(dmmChart.ChartAreas[0].AxisY.Title + " AC");
                    else if (prs.IsDC) SetTitle(dmmChart.ChartAreas[0].AxisY.Title + " DC");
                }
                //MessageBox.Show(prs.UnitOfMeasure);
                if ((prs.UnitOfMeasure == "°C") && (dmmChart.Series[0].Points.Count > 1))
                {
                    Double lc = dmmChart.Series[0].Points[dmmChart.Series[0].Points.Count - 1].YValues[0] + 273.15;
                    Double slc = dmmChart.Series[0].Points[dmmChart.Series[0].Points.Count - 2].YValues[0] + 273.15;
                    Double lctime = dmmChart.Series[0].Points[dmmChart.Series[0].Points.Count - 1].XValue;
                    Double slctime = dmmChart.Series[0].Points[dmmChart.Series[0].Points.Count - 2].XValue;
                    //mathparser.GetDQandPow(slc, lc, slctime, lctime, a, b, c, d, evar);
                    //integrator.SetValues(mathparser.DeltaQ, mathparser.Pow.ToString("F3"));
                    SetValues(lc,slc,lctime,slctime, elapsed, now);
                }
                //MessageBox.Show(data);
            }
        }
        private delegate void SetLbl(string value);
        public void SetLabel(string value)
        {
            if (this.dmmLbl.InvokeRequired)
            {
                SetLbl d = new SetLbl(SetLabel);
                Invoke(d, new object[] { value });
            }
            else
            {
                dmmLbl.Text = value;
            }
        }
        private delegate void SetChart(Double value, double elapsed, double now);
        public void SetDmmChart(Double value, double elapsed, double now)
        {
            if (this.dmmChart.InvokeRequired)
            {
                SetChart d = new SetChart(SetDmmChart);
                Invoke(d, new object[] { value, elapsed, now });
            }
            else
            {
                dmmChart.Series[0].Points.AddXY(elapsed, value, now);
            }
        }
        private delegate void SetChartTitle(string value);
        public void SetTitle(string value)
        {
            if (this.dmmChart.InvokeRequired)
            {
                SetChartTitle d = new SetChartTitle(SetTitle);
                Invoke(d, new object[] { value });
            }
            else
            {
                dmmChart.ChartAreas[0].AxisY.Title = value;
            }
        }
        private void startmultimBtn_Click(object sender, EventArgs e)
        {
            Double maxval = 0;
            if (dmmChart.Series[0].Points.Count > 0) maxval = dmmChart.Series[0].Points.Last().XValue;
            if ((logger.Elapsed.TotalSeconds+1) >= maxval)
            {
                string idselected = tsdmmList.SelectedItem.ToString();
                string vid;
                string pid;
                int vidstart = idselected.IndexOf("#");
                int separator = idselected.IndexOf("&");
                int pidend = idselected.IndexOf("#", vidstart + 1);
                if (!logger.IsRunning) logger.Start();
                log2running = true;
                vid = idselected.Substring((vidstart + 1), (separator - (vidstart + 1)));
                pid = idselected.Substring((separator + 1), (pidend - (separator + 1)));
                usb = new USBHIDDRIVER.USBInterface(vid, pid);
                usb.Connect();
                usb.enableUsbBufferEvent(LogDMM);
                Thread.Sleep(5);
                usb.startRead();
                tsstopmultimBtn.Enabled = true;
                tsdmmList.Enabled = false;
                tsstartmultimBtn.Enabled = false;
                dmmPnl.Enabled = true;
                loadprjBtn.Enabled = false;
                saveprjBtn.Enabled = false;
                prjlistTree.Enabled = false;
                toolStrip2.Enabled = false;
            }
            else
            {
                MessageBox.Show("Can't overwrite old chart data! First clear the chart or create a new experiment using the left toolbox", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }

        private void stopmultimBtn_Click(object sender, EventArgs e)
        {
            usb.stopRead();
            usb.Disconnect();
            tsdmmList.Enabled = true;
            tsstartmultimBtn.Enabled = true;
            tsstopmultimBtn.Enabled = false;
            if (!log1running)
            {
                logger.Stop();
                prjlistTree.Enabled = true;
                toolStrip2.Enabled = true;
                loadprjBtn.Enabled = true;
                saveprjBtn.Enabled = true;
            }
            log2running = false;
            dmmPnl.Enabled = false;
        }

        private void clearVolcraftChartToolStripMenuItem_Click(object sender, EventArgs e)
        {
            logChart.Series[0].Points.Clear();
            logChart.Series[1].Points.Clear();
            logger.Reset();
        }

        private void clearDMMChartToolStripMenuItem_Click(object sender, EventArgs e)
        {
            dmmChart.Series[0].Points.Clear();
            logger.Reset();
        }

        private void clearBothToolStripMenuItem_Click(object sender, EventArgs e)
        {
            logChart.Series[0].Points.Clear();
            logChart.Series[1].Points.Clear();
            dmmChart.Series[0].Points.Clear();
            logger.Reset();
        }

        private void menuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {

        }

        private void clearBothToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            clearVoltcraftChartToolStripMenuItem.Checked = false;
            clearVictorChartToolStripMenuItem.Checked = false;
            clearBothToolStripMenuItem_Click(sender, e);
        }

        private void clearVictorChartToolStripMenuItem_Click(object sender, EventArgs e)
        {
            clearVoltcraftChartToolStripMenuItem.Checked = false;
            clearBothToolStripMenuItem1.Checked = false;
            clearDMMChartToolStripMenuItem_Click(sender, e);
        }

        private void clearVoltcraftChartToolStripMenuItem_Click(object sender, EventArgs e)
        {
            clearVictorChartToolStripMenuItem.Checked = false;
            clearBothToolStripMenuItem1.Checked = false;
            clearVolcraftChartToolStripMenuItem_Click(sender, e);
        }

        private void toolStripSplitButton1_ButtonClick(object sender, EventArgs e)
        {
            if (clearBothToolStripMenuItem1.Checked) clearBothToolStripMenuItem_Click(sender, e);
            else if (clearVictorChartToolStripMenuItem.Checked) clearDMMChartToolStripMenuItem_Click(sender, e);
            else if (clearVoltcraftChartToolStripMenuItem.Checked) clearVolcraftChartToolStripMenuItem_Click(sender, e);
        }

        private void toolStripNumberControl1_Click(object sender, EventArgs e)
        {

        }

        private void Form1_Shown(object sender, EventArgs e)
        {
            tscomList.Focus();
        }

        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            if (!log1running)
            {
                tscomList.Items.Clear();
                string[] ArrayComPortsNames = null;
                int index = -1;
                string ComPortName = null;
                ArrayComPortsNames = SerialPort.GetPortNames();
                if (ArrayComPortsNames.Length > 0)
                {
                    do
                    {
                        index += 1;
                        tscomList.Items.Add((ArrayComPortsNames[index]));
                    }
                    while (!((ArrayComPortsNames[index] == ComPortName) ||
                                        (index == ArrayComPortsNames.GetUpperBound(0))));
                    if (index == ArrayComPortsNames.GetUpperBound(0))
                    {
                        ComPortName = ArrayComPortsNames[0];
                    }
                    tscomList.Text = ArrayComPortsNames[0];
                    tscomList.Enabled = true;
                    tsselectBtn.Enabled = true;
                } else
                {
                    tscomList.Enabled = false;
                    tsselectBtn.Enabled = false;
                }
            }
            if (!log2running)
            {
                tsdmmList.Items.Clear();
                USBHIDDRIVER.USBInterface usbl = new USBHIDDRIVER.USBInterface("vid_1244");
                String[] list = usbl.getDeviceList();
                if (list.Length == 0)
                {
                    tsdmmList.Enabled = false;
                    tsstartmultimBtn.Enabled = false;
                }
                else
                {
                    for (int i = 0; i < list.Length; i++)
                    {
                        tsdmmList.Items.Add(list[i]);
                    }
                    tsdmmList.SelectedIndex = 0;
                    tsdmmList.Enabled = true;
                    tsstartmultimBtn.Enabled = true;
                }
            }
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            //LOAD CUSTOM FONTS IN LABELS
            label2.Font = groupBox1.Font = groupBox3.Font = dmmPnl.Font = maxLbl.Font = minLbl.Font = relLbl.Font = DIGIfontBold1425;
            acLbl.Font = dcLbl.Font = autoLbl.Font = holdLbl.Font = DIGIfontBold24;
            label3.Font = label4.Font = DIGIfont975;
            currBox.Font = voltBox.Font = label5.Font = label6.Font = DIGIfont12;
            voltLbl.Font = currLbl.Font = DIGIfont36;
            heatbalanceBox.Font = powerBox.Font = enerLbl.Font = powLbl.Font = DIGIfontBold36;
            //END LOAD FONTS

            TreeNode newn = prjlistTree.Nodes.Add(DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString() + ":" + DateTime.Now.Second);
            prjlistTree.SelectedNode = newn;
            logchartStreams = new Dictionary<string, MemoryStream>();
            dmmchartStreams = new Dictionary<string, MemoryStream>();
            heatchartStreams = new Dictionary<string, MemoryStream>();
            powchartStreams = new Dictionary<string, MemoryStream>();
            mediumselected = new Dictionary<string, string>();
            if (File.Exists(argument))
            {
                try
                {
                    LoadFile(argument);
                    this.Text = "SaRS Instruman - [" + argument + "] open";
                    fileopened = argument;
                }
                catch
                {
                    MessageBox.Show("Error! Invalid file opened! Probably it has been saved from a previous version of InstruMan", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    Application.Exit();
                }
            }
            editmode = "";
            inputPnl.Location = new Point(-156, inputPnl.Location.Y);
        }
        bool NodeExists(string name)
        {
            bool exists = false;
            foreach (TreeNode node in prjlistTree.Nodes)
            {
                if (node.Text == name)
                    exists = true;
            }
            return exists;
        }
        private void toolStripButton3_Click(object sender, EventArgs e)
        {
            string nodesname =DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString() + ":" + DateTime.Now.Second;
            TreeNode newn = new TreeNode("");
            if (NodeExists(nodesname))
            {
                if (NodeExists(nodesname + "(1)"))
                {
                    if(!NodeExists(nodesname+"(2)"))
                        newn = prjlistTree.Nodes.Add(nodesname + "(2)");
                }
                else newn = prjlistTree.Nodes.Add(nodesname + "(1)");
            }
            else newn = prjlistTree.Nodes.Add(nodesname);
            if(newn.Text!="") prjlistTree.SelectedNode = newn;
        }

        private void toolStripButton4_Click(object sender, EventArgs e)
        {
            if (prjlistTree.SelectedNode != null)
            {
                logchartStreams.Remove(prjlistTree.SelectedNode.Text);
                dmmchartStreams.Remove(prjlistTree.SelectedNode.Text);
                heatchartStreams.Remove(prjlistTree.SelectedNode.Text);
                powchartStreams.Remove(prjlistTree.SelectedNode.Text);
                prjlistTree.SelectedNode.Remove();
            }
        }

        private void toolStripButton5_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Are you sure you want to delete all logs?", "Erasing logs", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.Yes)
            {
                logchartStreams.Clear();
                dmmchartStreams.Clear();
                heatchartStreams.Clear();
                powchartStreams.Clear();
                prjlistTree.Nodes.Clear();
                logChart.Series[0].Points.Clear();
                logChart.Series[1].Points.Clear();
                dmmChart.Series[0].Points.Clear();
                heatChart.Series[0].Points.Clear();
                heatChart.Series[1].Points.Clear();
                powChart.Series[0].Points.Clear();
                powChart.Series[1].Points.Clear();
            }
        }


        private void toolStripButton6_Click(object sender, EventArgs e)
        {
            if(prjlistTree.SelectedNode!=null) prjlistTree.SelectedNode.BeginEdit();
        }

        private void prjlistTree_BeforeSelect(object sender, TreeViewCancelEventArgs e)
        {
            MemoryStream logsys = new MemoryStream();
            MemoryStream dmmsys = new MemoryStream();
            MemoryStream heatsys = new MemoryStream();
            MemoryStream powsys = new MemoryStream();
            string mselsys = "";
            logChart.Serializer.Save(logsys);
            dmmChart.Serializer.Save(dmmsys);
            heatChart.Serializer.Save(heatsys);
            powChart.Serializer.Save(powsys);
            if(mediumList.SelectedItem!=null) mselsys = mediumList.SelectedItem.ToString();

            if (prjlistTree.SelectedNode != null)
            {
                if(logchartStreams.ContainsKey(prjlistTree.SelectedNode.Text))
                {
                    logchartStreams.Remove(prjlistTree.SelectedNode.Text);
                }
                if (dmmchartStreams.ContainsKey(prjlistTree.SelectedNode.Text))
                {
                    dmmchartStreams.Remove(prjlistTree.SelectedNode.Text);
                }
                if (heatchartStreams.ContainsKey(prjlistTree.SelectedNode.Text))
                {
                    heatchartStreams.Remove(prjlistTree.SelectedNode.Text);
                }
                if (powchartStreams.ContainsKey(prjlistTree.SelectedNode.Text))
                {
                    powchartStreams.Remove(prjlistTree.SelectedNode.Text);
                }
                if (mediumselected.ContainsKey(prjlistTree.SelectedNode.Text))
                {
                    mediumselected.Remove(prjlistTree.SelectedNode.Text);
                }
                logchartStreams.Add(prjlistTree.SelectedNode.Text, logsys);
                dmmchartStreams.Add(prjlistTree.SelectedNode.Text, dmmsys);
                heatchartStreams.Add(prjlistTree.SelectedNode.Text, heatsys);
                powchartStreams.Add(prjlistTree.SelectedNode.Text, powsys);
                mediumselected.Add(prjlistTree.SelectedNode.Text, mselsys);
            }
        }

        private void prjlistTree_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (prjlistTree.SelectedNode != null)
            {
                if ((logchartStreams != null)&& (dmmchartStreams != null)&& (heatchartStreams != null) && (powchartStreams != null))
                { 
                    if (logchartStreams.ContainsKey(prjlistTree.SelectedNode.Text) && dmmchartStreams.ContainsKey(prjlistTree.SelectedNode.Text) && heatchartStreams.ContainsKey(prjlistTree.SelectedNode.Text) && powchartStreams.ContainsKey(prjlistTree.SelectedNode.Text) && mediumselected.ContainsKey(prjlistTree.SelectedNode.Text))
                    {
                        MemoryStream logsys = new MemoryStream();
                        MemoryStream dmmsys = new MemoryStream();
                        MemoryStream heatsys = new MemoryStream();
                        MemoryStream powsys = new MemoryStream();
                        string mselsys = "";
                        logsys = logchartStreams[prjlistTree.SelectedNode.Text];
                        dmmsys = dmmchartStreams[prjlistTree.SelectedNode.Text];
                        heatsys = heatchartStreams[prjlistTree.SelectedNode.Text];
                        powsys = powchartStreams[prjlistTree.SelectedNode.Text];
                        mselsys = mediumselected[prjlistTree.SelectedNode.Text];
                        logChart.Serializer.Load(logsys);
                        dmmChart.Serializer.Load(dmmsys);
                        heatChart.Serializer.Load(heatsys);
                        powChart.Serializer.Load(powsys);
                        mediumList.SelectedItem = mselsys;

                        if (heatChart.Series[0].Points.Count > 0)
                        {
                            heatbalanceBox.Text = heatChart.Series[0].Points.Last().YValues[0].ToString("F3");
                        }
                        else heatbalanceBox.Text = "0";
                        if (powChart.Series[0].Points.Count > 0)
                        {
                            enerLbl.Text = powChart.Series[0].Points.Last().YValues[0].ToString("N3");
                        }
                        else enerLbl.Text = "0";
                    }
                    else
                    {
                        logChart.Series[0].Points.Clear();
                        logChart.Series[1].Points.Clear();
                        dmmChart.Series[0].Points.Clear();
                        heatChart.Series[0].Points.Clear();
                        heatChart.Series[1].Points.Clear();
                        powChart.Series[0].Points.Clear();
                        powChart.Series[1].Points.Clear();
                        if(mediumList.Items.Count>0) mediumList.SelectedIndex = 0;
                        heatbalanceBox.Text = "0";
                        enerLbl.Text = "0";
                        MemoryStream logsys = new MemoryStream();
                        MemoryStream dmmsys = new MemoryStream();
                        MemoryStream heatsys = new MemoryStream();
                        MemoryStream powsys = new MemoryStream();
                        logChart.Serializer.Save(logsys);
                        dmmChart.Serializer.Save(dmmsys);
                        heatChart.Serializer.Save(heatsys);
                        powChart.Serializer.Save(powsys);
                        if (logchartStreams.ContainsKey(prjlistTree.SelectedNode.Text))
                        {
                            logchartStreams.Remove(prjlistTree.SelectedNode.Text);
                        }
                        if (dmmchartStreams.ContainsKey(prjlistTree.SelectedNode.Text))
                        {
                            dmmchartStreams.Remove(prjlistTree.SelectedNode.Text);
                        }
                        if (heatchartStreams.ContainsKey(prjlistTree.SelectedNode.Text))
                        {
                            heatchartStreams.Remove(prjlistTree.SelectedNode.Text);
                        }
                        if (powchartStreams.ContainsKey(prjlistTree.SelectedNode.Text))
                        {
                            powchartStreams.Remove(prjlistTree.SelectedNode.Text);
                        }
                        if (mediumselected.ContainsKey(prjlistTree.SelectedNode.Text))
                        {
                            mediumselected.Remove(prjlistTree.SelectedNode.Text);
                        }
                        logchartStreams.Add(prjlistTree.SelectedNode.Text, logsys);
                        dmmchartStreams.Add(prjlistTree.SelectedNode.Text, dmmsys);
                        heatchartStreams.Add(prjlistTree.SelectedNode.Text, heatsys);
                        powchartStreams.Add(prjlistTree.SelectedNode.Text, powsys);
                        if(mediumList.SelectedItem!=null) mediumselected.Add(prjlistTree.SelectedNode.Text, mediumList.SelectedItem.ToString());
                    }
                }
            }
        }
        private void prjlistTree_BeforeLabelEdit(object sender, NodeLabelEditEventArgs e)
        {
            startname = prjlistTree.SelectedNode.Text;
            if (!logchartStreams.ContainsKey(startname))
            {
                MemoryStream tmp = new MemoryStream();
                logChart.Serializer.Save(tmp);
                logchartStreams.Add(startname, tmp);
            }
            if (!dmmchartStreams.ContainsKey(startname))
            {
                MemoryStream tmp = new MemoryStream();
                dmmChart.Serializer.Save(tmp);
                dmmchartStreams.Add(startname, tmp);
            }
            if (!heatchartStreams.ContainsKey(startname))
            {
                MemoryStream tmp = new MemoryStream();
                heatChart.Serializer.Save(tmp);
                heatchartStreams.Add(startname, tmp);
            }
            if (!powchartStreams.ContainsKey(startname))
            {
                MemoryStream tmp = new MemoryStream();
                powChart.Serializer.Save(tmp);
                powchartStreams.Add(startname, tmp);
            }
            if (!mediumselected.ContainsKey(startname))
            {
                if(mediumList.SelectedItem!=null) mediumselected.Add(startname, mediumList.SelectedItem.ToString());
            }
        }

        private void prjlistTree_AfterLabelEdit(object sender, NodeLabelEditEventArgs e)
        {
            if ((e.Label == "")||(e.Label==null))
                e.CancelEdit = true;
            else if (e.Label == startname)
                e.CancelEdit = true;
            else if (logchartStreams.ContainsKey(e.Label) || prjlistTree.Nodes.ContainsKey(e.Label))
            {
                //MessageBox.Show("The name you chosen already exists!", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                err.Hide(this);
                err.ToolTipTitle = "Error!";
                err.ToolTipIcon = ToolTipIcon.Error;
                err.IsBalloon = true;
                err.Show("The name you entered already exists!", this, new Point(prjlistTree.SelectedNode.Bounds.X+50, prjlistTree.SelectedNode.Bounds.Y+0), 2000);
                e.CancelEdit = true;
            }
            else
            {
                if (logchartStreams.ContainsKey(startname) && dmmchartStreams.ContainsKey(startname) && heatchartStreams.ContainsKey(startname) && powchartStreams.ContainsKey(startname))
                {
                    MemoryStream logtemp = logchartStreams[startname];
                    MemoryStream dmmtemp = dmmchartStreams[startname];
                    MemoryStream heattemp = heatchartStreams[startname];
                    MemoryStream powtemp = powchartStreams[startname];
                    string medseltemp = "";
                    if (mediumselected.ContainsKey(startname)) medseltemp = mediumselected[startname];

                    logchartStreams.Remove(startname);
                    logchartStreams.Add(e.Label, logtemp);

                    dmmchartStreams.Remove(startname);
                    dmmchartStreams.Add(e.Label, dmmtemp);

                    heatchartStreams.Remove(startname);
                    heatchartStreams.Add(e.Label, heattemp);

                    powchartStreams.Remove(startname);
                    powchartStreams.Add(e.Label, powtemp);

                    mediumselected.Remove(startname);
                    if (medseltemp != "") mediumselected.Add(e.Label, medseltemp);
                }
            }
        }

        private void saveprjBtn_Click(object sender, EventArgs e)
        {
            if ((logchartStreams != null) && (dmmchartStreams != null) && (heatchartStreams != null) && (powchartStreams != null))
            {
                SaveFileDialog filepath = new SaveFileDialog();
                filepath.Filter = "InstruMan Logged Data|*.ild";
                filepath.Title = "Save Logged Data";
                if (filepath.ShowDialog() == DialogResult.OK)
                {
                    if (filepath.FileName != "")
                    {
                        if (System.IO.File.Exists(filepath.FileName)) System.IO.File.Delete(filepath.FileName);
                        SaveFile(filepath.FileName);
                        this.Text = "SaRS InstruMan - [" + filepath.FileName + "] open";
                        fileopened = filepath.FileName;
                    }
                }
            }
        }

        private void loadprjBtn_Click(object sender, EventArgs e)
        {
            OpenFileDialog filepath = new OpenFileDialog();
            filepath.Filter = "InstruMan Logged Data|*.ild";
            filepath.Title = "Open Logged Data";
            if (filepath.ShowDialog() == DialogResult.OK)
            {
                if (filepath.FileName != "")
                {
                    string tmpfile = this.Text;
                    string tmpfopen = fileopened;
                    try
                    {
                        if (Settings.AutoSave) AutoSave();
                        else {
                            if (MessageBox.Show("Do you want to save your current project before opening a different one?", "Opening a different project", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                            {
                                if (fileopened != "") SaveFile(fileopened);
                                else saveprjBtn_Click(this, EventArgs.Empty);
                            }
                        }
                        LoadFile(filepath.FileName);
                        this.Text = "SaRS InstruMan - [" + filepath.FileName + "] open";
                        fileopened = filepath.FileName;
                    }
                    catch
                    {
                        MessageBox.Show("Error! Invalid file opened! Probably it has been saved from a previous version of InstruMan", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        this.Text = tmpfile;
                        fileopened = tmpfopen;
                        LoadFile(fileopened);
                    }
                }
            }
       }

        private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
        {

        }

        private void logChart_MouseClick(object sender, MouseEventArgs e)
        {

        }

        private void exportToImageToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (sender == logexpBtn)
            {
                SaveFileDialog export = new SaveFileDialog();
                export.Title = "Export to image file";
                export.AddExtension = true;
                export.Filter = "JPG File|*.jpg|PNG file|*.png|Bitmap|*.bmp";
                export.FilterIndex = 1;
                if (export.ShowDialog() == DialogResult.OK)
                {
                    if (export.FileName != "")
                    {
                        switch (export.FilterIndex)
                        {
                            case 1:
                                {
                                    //JPG
                                    logChart.SaveImage(export.FileName, System.Drawing.Imaging.ImageFormat.Jpeg);
                                    break;
                                }
                            case 2:
                                {
                                    // PNG
                                    logChart.SaveImage(export.FileName, System.Drawing.Imaging.ImageFormat.Png);
                                    break;
                                }
                            case 3:
                                {
                                    //BMP
                                    logChart.SaveImage(export.FileName, System.Drawing.Imaging.ImageFormat.Bmp);
                                    break;
                                }
                        }
                    }
                }
            }
            else if (sender==dmmexpBtn)
            {
                SaveFileDialog export = new SaveFileDialog();
                export.Title = "Export to image file";
                export.AddExtension = true;
                export.Filter = "JPG File|*.jpg|PNG file|*.png|Bitmap|*.bmp";
                export.FilterIndex = 1;
                if (export.ShowDialog() == DialogResult.OK)
                {
                    if (export.FileName != "")
                    {
                        switch (export.FilterIndex)
                        {
                            case 1:
                                {
                                    //JPG
                                    dmmChart.SaveImage(export.FileName, System.Drawing.Imaging.ImageFormat.Jpeg);
                                    break;
                                }
                            case 2:
                                {
                                    // PNG
                                    dmmChart.SaveImage(export.FileName, System.Drawing.Imaging.ImageFormat.Png);
                                    break;
                                }
                            case 3:
                                {
                                    //BMP
                                    dmmChart.SaveImage(export.FileName, System.Drawing.Imaging.ImageFormat.Bmp);
                                    break;
                                }
                        }
                    }
                }
            }
            else if (sender == heatexpBtn)
            {
                SaveFileDialog export = new SaveFileDialog();
                export.Title = "Export to image file";
                export.AddExtension = true;
                export.Filter = "JPG File|*.jpg|PNG file|*.png|Bitmap|*.bmp";
                export.FilterIndex = 1;
                if (export.ShowDialog() == DialogResult.OK)
                {
                    if (export.FileName != "")
                    {
                        switch (export.FilterIndex)
                        {
                            case 1:
                                {
                                    //JPG
                                    heatChart.SaveImage(export.FileName, System.Drawing.Imaging.ImageFormat.Jpeg);
                                    break;
                                }
                            case 2:
                                {
                                    // PNG
                                    heatChart.SaveImage(export.FileName, System.Drawing.Imaging.ImageFormat.Png);
                                    break;
                                }
                            case 3:
                                {
                                    //BMP
                                    heatChart.SaveImage(export.FileName, System.Drawing.Imaging.ImageFormat.Bmp);
                                    break;
                                }
                        }
                    }
                }
            }
            else if (sender == powexpBtn)
            {
                SaveFileDialog export = new SaveFileDialog();
                export.Title = "Export to image file";
                export.AddExtension = true;
                export.Filter = "JPG File|*.jpg|PNG file|*.png|Bitmap|*.bmp";
                export.FilterIndex = 1;
                if (export.ShowDialog() == DialogResult.OK)
                {
                    if (export.FileName != "")
                    {
                        switch (export.FilterIndex)
                        {
                            case 1:
                                {
                                    //JPG
                                    powChart.SaveImage(export.FileName, System.Drawing.Imaging.ImageFormat.Jpeg);
                                    break;
                                }
                            case 2:
                                {
                                    // PNG
                                    powChart.SaveImage(export.FileName, System.Drawing.Imaging.ImageFormat.Png);
                                    break;
                                }
                            case 3:
                                {
                                    //BMP
                                    powChart.SaveImage(export.FileName, System.Drawing.Imaging.ImageFormat.Bmp);
                                    break;
                                }
                        }
                    }
                }
            }
        }

        private void dmmsaveimageCMenu_Opening(object sender, CancelEventArgs e)
        {

        }

        private void heatsaveimageCMenu_Opening(object sender, CancelEventArgs e)
        {
            
        }

        private void MainForm_Paint(object sender, PaintEventArgs e)
        {
            /*using (LinearGradientBrush brush = new LinearGradientBrush(this.ClientRectangle,
                                                               Color.WhiteSmoke,
                                                               Color.LightGray,
                                                               180F))
            {
                e.Graphics.FillRectangle(brush, this.ClientRectangle);
            }*/
        }

        private void startPowBtn_Click(object sender, EventArgs e)
        {
            double maxval=0;
            if (powChart.Series[0].Points.Count > 0) maxval = powChart.Series[0].Points.Last().XValue;
            if ((logger.Elapsed.TotalSeconds + 1) >= maxval)
            {
                shouldlogpower = true;
                startPowBtn.Enabled = false;
                stopPowBtn.Enabled = true;
            }
            else
            {
                MessageBox.Show("Can't overwrite old chart data! First clear the chart or create a new experiment", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }

        private void stopPowBtn_Click(object sender, EventArgs e)
        {
            shouldlogpower = false;
            startPowBtn.Enabled = true;
            stopPowBtn.Enabled = false;
        }

        private void clearPowBtn_Click(object sender, EventArgs e)
        {
            powChart.Series[0].Points.Clear();
            powChart.Series[1].Points.Clear();
            enerLbl.Text = "0";
            powLbl.Text = "0";
        }

        private void CreateChart(Excel.Worksheet xlWorkSheet, string xFirst, string xLast, string y1First, string y1Last, string y2First, string y2Last, string xLabel, string y1Label, string y2Label, string chartTitle)
        {
            Excel.ChartObjects xlCharts = (Excel.ChartObjects)xlWorkSheet.ChartObjects(Type.Missing);
            Excel.ChartObject myChart = (Excel.ChartObject)xlCharts.Add(450, 80, 600, 250);
            Excel.Chart chartPage = myChart.Chart;

            chartPage.ChartType = Excel.XlChartType.xlXYScatterLines;
            chartPage.HasTitle = true;
            chartPage.ChartTitle.Text = chartTitle;

            Excel.SeriesCollection XlSeriesColl = (Excel.SeriesCollection)chartPage.SeriesCollection();
            Excel.Range xValRange = xlWorkSheet.Range[xFirst, xLast];

            Excel.Series vSeries = XlSeriesColl.NewSeries();
            vSeries.Values = xlWorkSheet.Range[y1First, y1Last];
            vSeries.XValues = xValRange;
            vSeries.Name = y1Label;
            vSeries.AxisGroup = Excel.XlAxisGroup.xlPrimary;

            Excel.Series cSeries = XlSeriesColl.NewSeries();
            cSeries.Values = xlWorkSheet.Range[y2First, y2Last];
            cSeries.XValues = xValRange;
            cSeries.Name = y2Label;
            cSeries.AxisGroup = Excel.XlAxisGroup.xlSecondary;

            var yAxisP = (Excel.Axis)chartPage.Axes(Excel.XlAxisType.xlValue, Excel.XlAxisGroup.xlPrimary);
            yAxisP.HasTitle = true;
            yAxisP.AxisTitle.Text = y1Label;
            yAxisP.AxisTitle.Orientation = Excel.XlOrientation.xlUpward;

            var yAxisS = (Excel.Axis)chartPage.Axes(Excel.XlAxisType.xlValue, Excel.XlAxisGroup.xlSecondary);
            yAxisS.HasTitle = true;
            yAxisS.AxisTitle.Text = y2Label;
            yAxisS.AxisTitle.Orientation = Excel.XlOrientation.xlUpward;

            var xAxis = (Excel.Axis)chartPage.Axes(Excel.XlAxisType.xlCategory, Excel.XlAxisGroup.xlPrimary);
            xAxis.HasTitle = true;
            xAxis.AxisTitle.Text = xLabel;
        }

        private void CreateChart(Excel.Worksheet xlWorkSheet, string xFirst, string xLast, string yFirst, string yLast, string xLabel, string yLabel, string chartTitle)
        {
            Excel.ChartObjects xlCharts = (Excel.ChartObjects)xlWorkSheet.ChartObjects(Type.Missing);
            Excel.ChartObject myChart = (Excel.ChartObject)xlCharts.Add(350, 80, 600, 250);
            Excel.Chart chartPage = myChart.Chart;

            chartPage.ChartType = Excel.XlChartType.xlXYScatterLines;
            chartPage.HasTitle = true;
            chartPage.ChartTitle.Text = chartTitle;

            Excel.SeriesCollection XlSeriesColl = (Excel.SeriesCollection)chartPage.SeriesCollection();
            Excel.Range xValRange = xlWorkSheet.Range[xFirst, xLast];

            Excel.Series vSeries = XlSeriesColl.NewSeries();
            vSeries.Values = xlWorkSheet.Range[yFirst, yLast];
            vSeries.XValues = xValRange;
            vSeries.Name = yLabel;
            vSeries.AxisGroup = Excel.XlAxisGroup.xlPrimary;

            var yAxisP = (Excel.Axis)chartPage.Axes(Excel.XlAxisType.xlValue, Excel.XlAxisGroup.xlPrimary);
            yAxisP.HasTitle = true;
            yAxisP.AxisTitle.Text = yLabel;
            yAxisP.AxisTitle.Orientation = Excel.XlOrientation.xlUpward;

            var xAxis = (Excel.Axis)chartPage.Axes(Excel.XlAxisType.xlCategory, Excel.XlAxisGroup.xlPrimary);
            xAxis.HasTitle = true;
            xAxis.AxisTitle.Text = xLabel;
        }
        public class NewProgressBar : ProgressBar
        {
            public Brush CustomColor;
            public NewProgressBar()
            {
                this.SetStyle(ControlStyles.UserPaint, true);
                CustomColor = Brushes.LightBlue;
            }

            protected override void OnPaint(PaintEventArgs e)
            {
                Rectangle rec = e.ClipRectangle;

                rec.Width = (int)(rec.Width * ((double)Value / Maximum)) - 4;
                if (ProgressBarRenderer.IsSupported)
                    ProgressBarRenderer.DrawHorizontalBar(e.Graphics, e.ClipRectangle);
                rec.Height = rec.Height - 4;
                e.Graphics.FillRectangle(CustomColor, 2, 2, rec.Width, rec.Height);
            }
        }

        private void exportexcelBtn_Click(object sender, EventArgs e)
        {
            SaveFileDialog filepath = new SaveFileDialog();
            filepath.Filter = "Excel Spreadsheet|*.xlsx";
            filepath.Title = "Save Logged Data";
            filepath.ShowDialog();
            int max = logChart.Series["Voltage"].Points.Count + dmmChart.Series[0].Points.Count + heatChart.Series[0].Points.Count + powChart.Series[0].Points.Count;
            if (filepath.FileName != "")
            {
                if (System.IO.File.Exists(filepath.FileName)) System.IO.File.Delete(filepath.FileName);
                 
                    StatusBar stat = new StatusBar();
                    stat.Dock = DockStyle.Bottom;
                    NewProgressBar progress = new NewProgressBar();
                    progress.Minimum = 0;
                if (max > 0) progress.Maximum = max;
                else progress.Maximum = 1;
                    progress.Value = 0;
                    progress.Dock = DockStyle.Fill;
                    progress.Width = 300;
                    progress.Style = ProgressBarStyle.Continuous;
                    progress.Step = 1;
                    stat.Controls.Add(progress);
                    this.Controls.Add(stat);
                if (max == 0) progress.PerformStep();
                Excel.Application xlApp = new Excel.Application();
                    if (xlApp == null)
                    {
                        MessageBox.Show("Excel is not properly installed!!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    else
                    {
                        Excel.Workbook xlWorkBook;
                        Excel.Worksheet xlVoltSheet;
                        Excel.Worksheet xlDMMSheet;
                        Excel.Worksheet xlHeatSheet;
                        Excel.Worksheet xlPowSheet;

                        object misValue = System.Reflection.Missing.Value;
                        xlWorkBook = xlApp.Workbooks.Add(Excel.XlWBATemplate.xlWBATWorksheet);
                        xlVoltSheet = xlWorkBook.Worksheets.Item[1];
                        xlVoltSheet.Name = "Voltcraft data";
                        //xlVoltSheet.Cells[1, 1] = "Sheet 1 content";
                        string last;
                        /* ADDING VOLTCRAFT DATA */
                        last = (logChart.Series["Voltage"].Points.Count + 1).ToString();
                        xlVoltSheet.Cells[1, 2] = "Time";
                        xlVoltSheet.Cells[1, 1] = "Time (s)";
                        xlVoltSheet.Cells[1, 3] = "Voltage";
                        xlVoltSheet.Cells[1, 4] = "Current";
                        for (int i = 0; i < logChart.Series["Voltage"].Points.Count; i++)
                        {
                            xlVoltSheet.Cells[i + 2, 1] = logChart.Series["Voltage"].Points[i].XValue;
                            xlVoltSheet.Cells[i + 2, 2] = "'"+DateTime.FromOADate(logChart.Series["Voltage"].Points[i].YValues[1]).ToLongTimeString() + "." + DateTime.FromOADate(logChart.Series["Voltage"].Points[i].YValues[1]).Millisecond.ToString();
                            xlVoltSheet.Cells[i + 2, 3] = logChart.Series["Voltage"].Points[i].YValues[0];
                            xlVoltSheet.Cells[i + 2, 4] = logChart.Series["Current"].Points[i].YValues[0];
                            progress.PerformStep();
                        }
                        // CREATING CHART
                        CreateChart(xlVoltSheet, "A2", "A" + last, "C2", "C" + last, "D2", "D" + last, "Time (s)", "Voltage", "Current", "Voltcraft Data");

                        /* ADDING DMM DATA */
                        last = (dmmChart.Series[0].Points.Count + 1).ToString();
                        if (xlWorkBook.Worksheets.Count < 2)
                        {
                            xlDMMSheet = (Excel.Worksheet)xlWorkBook.Worksheets.Add(xlWorkBook.Worksheets[1], Type.Missing, Type.Missing, Type.Missing);
                        }
                        else
                            xlDMMSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(2);
                        xlDMMSheet.Name = "DMM Data";
                        xlDMMSheet.Cells[1, 1] = "Time (s)";
                        xlDMMSheet.Cells[1, 2] = "Time";
                        xlDMMSheet.Cells[1, 3] = dmmChart.ChartAreas[0].AxisY.Title;
                        for (int i = 0; i < dmmChart.Series[0].Points.Count; i++)
                        {
                            xlDMMSheet.Cells[i + 2, 1] = dmmChart.Series[0].Points[i].XValue;
                            xlDMMSheet.Cells[i + 2, 2] = "'" + DateTime.FromOADate(dmmChart.Series[0].Points[i].YValues[1]).ToLongTimeString() + "." + DateTime.FromOADate(dmmChart.Series[0].Points[i].YValues[1]).Millisecond.ToString();
                            xlDMMSheet.Cells[i + 2, 3] = dmmChart.Series[0].Points[i].YValues[0];
                            progress.PerformStep();
                        }
                        //CREATING CHART
                        CreateChart(xlDMMSheet, "A2", "A" + last, "C2", "C" + last, "Time (s)", dmmChart.ChartAreas[0].AxisY.Title, "DMM Data");

                        /* ADDING HEAT EXCHANGE DATA */
                        last = (heatChart.Series[0].Points.Count + 1).ToString();
                        if (xlWorkBook.Worksheets.Count < 3)
                        {
                            xlHeatSheet = (Excel.Worksheet)xlWorkBook.Worksheets.Add(xlWorkBook.Worksheets[1], Type.Missing, Type.Missing, Type.Missing);
                        }
                        else
                            xlHeatSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(3);
                        xlHeatSheet.Name = "Heat Exchange Data";
                        xlHeatSheet.Cells[1, 1] = "Time (s)";
                        xlHeatSheet.Cells[1, 2] = "Time";
                        xlHeatSheet.Cells[1, 3] = "Heat balance(KJ / kg)";
                        xlHeatSheet.Cells[1, 4] = "Heat Exchange Rate (KW / kg)";
                        for (int i = 0; i < heatChart.Series[0].Points.Count; i++)
                        {
                            xlHeatSheet.Cells[i + 2, 1] = heatChart.Series[0].Points[i].XValue;
                            xlHeatSheet.Cells[i + 2, 2] = "'" + DateTime.FromOADate(heatChart.Series[0].Points[i].YValues[1]).ToLongTimeString() + "." + DateTime.FromOADate(heatChart.Series[0].Points[i].YValues[1]).Millisecond.ToString();
                            xlHeatSheet.Cells[i + 2, 3] = heatChart.Series[0].Points[i].YValues[0];
                            xlHeatSheet.Cells[i + 2, 4] = heatChart.Series[1].Points[i].YValues[0];
                            progress.PerformStep();
                        }
                        //CREATING CHART
                        CreateChart(xlHeatSheet, "A2", "A" + last, "C2", "C" + last, "D2", "D" + last, "Time (s)", "Heat balance (KJ / kg)", "Heat Exchange Rate (KW / kg)", "Heat Exchange Data");

                        /* ADDING POWER DATA */
                        last = (powChart.Series[0].Points.Count + 1).ToString();
                        if (xlWorkBook.Worksheets.Count < 4)
                        {
                            xlPowSheet = (Excel.Worksheet)xlWorkBook.Worksheets.Add(xlWorkBook.Worksheets[1], Type.Missing, Type.Missing, Type.Missing);
                        }
                        else
                            xlPowSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(4);
                        xlPowSheet.Name = "Power Consumption Data";
                        xlPowSheet.Cells[1, 1] = "Time (s)";
                        xlPowSheet.Cells[1, 2] = "Time";
                        xlPowSheet.Cells[1, 3] = "Energy Consumed (J)";
                        xlPowSheet.Cells[1, 4] = "Power Consumption (W)";
                        for (int i = 0; i < powChart.Series[0].Points.Count; i++)
                        {
                            xlPowSheet.Cells[i + 2, 1] = powChart.Series[0].Points[i].XValue;
                            xlPowSheet.Cells[i + 2, 2] = "'" + DateTime.FromOADate(powChart.Series[0].Points[i].YValues[1]).ToLongTimeString() + "." + DateTime.FromOADate(powChart.Series[0].Points[i].YValues[1]).Millisecond.ToString();
                            xlPowSheet.Cells[i + 2, 3] = powChart.Series[0].Points[i].YValues[0];
                            xlPowSheet.Cells[i + 2, 4] = powChart.Series[1].Points[i].YValues[0];
                            progress.PerformStep();
                        }
                        //CREATING CHART
                        CreateChart(xlPowSheet, "A2", "A" + last, "C2", "C" + last, "D2", "D" + last, "Time (s)", "Energy Consumed (J)", "Power Consumption (W)", "Power Consumption Data");

                        xlWorkBook.SaveAs(filepath.FileName, Excel.XlFileFormat.xlOpenXMLWorkbook, Missing.Value,
    Missing.Value, false, false, Excel.XlSaveAsAccessMode.xlNoChange,
    Excel.XlSaveConflictResolution.xlUserResolution, true,
    Missing.Value, Missing.Value, Missing.Value);
                        xlApp.Quit();
                        releaseObject(xlVoltSheet);
                        releaseObject(xlDMMSheet);
                        releaseObject(xlHeatSheet);
                        releaseObject(xlPowSheet);
                        releaseObject(xlWorkBook);
                        releaseObject(xlApp);
                        progress.Update();
                        progress.CustomColor = Brushes.LightGreen;
                        progress.PerformStep();
                        Thread.Sleep(2000);
                        this.Controls.Remove(stat);
                    }
                
            }
        }


        private void releaseObject(object obj) { try { System.Runtime.InteropServices.Marshal.ReleaseComObject(obj); obj = null; } catch (Exception ex) { obj = null; MessageBox.Show("Exception Occured while releasing object " + ex.ToString()); } finally { GC.Collect(); } }

        private void syncedStartBtn_Click(object sender, EventArgs e)
        {
            if (tsselectBtn.Enabled) button1_Click(this, EventArgs.Empty);
            if(tsstartmultimBtn.Enabled) startmultimBtn_Click(this, EventArgs.Empty);
            if(tsbutton1.Enabled) startheatlogging_Click(this, EventArgs.Empty);
            if(startPowBtn.Enabled) startPowBtn_Click(this, EventArgs.Empty);
        }

        private void toolStripButton7_Click(object sender, EventArgs e)
        {
            if (tscloseBtn.Enabled) closeBtn_Click(this, EventArgs.Empty);
            if (tsstopmultimBtn.Enabled) stopmultimBtn_Click(this, EventArgs.Empty);
            if (tsbutton2.Enabled) stopheatlogging_Click(this, EventArgs.Empty);
            if (stopPowBtn.Enabled) stopPowBtn_Click(this, EventArgs.Empty);
        }

        private void clearallBtn_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Are you sure you want to clear all charts?", "Confirm!", MessageBoxButtons.YesNo, MessageBoxIcon.Question)==DialogResult.Yes)
            {
                dmmChart.Series[0].Points.Clear();
                logChart.Series[0].Points.Clear();
                logChart.Series[1].Points.Clear();
                heatChart.Series[0].Points.Clear();
                heatChart.Series[1].Points.Clear();
                powChart.Series[0].Points.Clear();
                powChart.Series[1].Points.Clear();
                heatbalanceBox.Text = "0";
                powerBox.Text = "0";
                enerLbl.Text = "0";
                powLbl.Text = "0";
            }
        }

        private void exportToExcelSpreadsheetToolStripMenuItem_Click(object sender, EventArgs e)
        {
            exportexcelBtn_Click(this, EventArgs.Empty);
        }

        private void prjlistTree_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                TreeNode selected = prjlistTree.GetNodeAt(prjlistTree.PointToClient(Cursor.Position));
                if (selected != null)
                {
                    prjlistTree.SelectedNode = selected;
                }
            }
        }

        private void mediumList_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                int selected = mediumList.IndexFromPoint(mediumList.PointToClient(Cursor.Position));
                if (selected >= 0)
                {
                    mediumList.SelectedIndex = selected;
                }
            }
        }

        private void MainForm_Resize(object sender, EventArgs e)
        {
        }

        private void mainPage_Paint(object sender, PaintEventArgs e)
        {
            using (LinearGradientBrush brush = new LinearGradientBrush(this.ClientRectangle,
                                                               Color.White,
                                                               Color.LightGray,
                                                               90F))
            {
                e.Graphics.FillRectangle(brush, this.ClientRectangle);
            }
        }

        private void mainPage_Resize(object sender, EventArgs e)
        {
            
        }

        private void heatexchangePage_Paint(object sender, PaintEventArgs e)
        {
            using (LinearGradientBrush brush = new LinearGradientBrush(this.ClientRectangle,
                                                               Color.White,
                                                               Color.LightGray,
                                                               90F))
            {
                e.Graphics.FillRectangle(brush, this.ClientRectangle);
            }
        }

        private void powerPage_Paint(object sender, PaintEventArgs e)
        {
            using (LinearGradientBrush brush = new LinearGradientBrush(this.ClientRectangle,
                                                               Color.White,
                                                               Color.LightGray,
                                                               90F))
            {
                e.Graphics.FillRectangle(brush, this.ClientRectangle);
            }
        }

        private void heatIntegratorToolStripMenuItem_Click(object sender, EventArgs e)
        {
            
        }

        private void toolStripButton8_Click(object sender, EventArgs e)
        {
            if (Settings.AutoSave) AutoSave();
            else {
                if (MessageBox.Show("Do you want to save your current project before creating a new one?", "Creating a new project", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    if (fileopened != "") SaveFile(fileopened);
                    else saveprjBtn_Click(this, EventArgs.Empty);
                }
            }
            toolStripButton7_Click(this, EventArgs.Empty);
            /* CLEARING ALL CHARTS */
            dmmChart.Series[0].Points.Clear();
            logChart.Series[0].Points.Clear();
            logChart.Series[1].Points.Clear();
            heatChart.Series[0].Points.Clear();
            heatChart.Series[1].Points.Clear();
            powChart.Series[0].Points.Clear();
            powChart.Series[1].Points.Clear();
            heatbalanceBox.Text = "0";
            powerBox.Text = "0";
            enerLbl.Text = "0";
            powLbl.Text = "0";
            /* CLEARING ALL LOGS */
            logchartStreams.Clear();
            dmmchartStreams.Clear();
            heatchartStreams.Clear();
            powchartStreams.Clear();
            prjlistTree.Nodes.Clear();
            logChart.Series[0].Points.Clear();
            logChart.Series[1].Points.Clear();
            dmmChart.Series[0].Points.Clear();
            heatChart.Series[0].Points.Clear();
            heatChart.Series[1].Points.Clear();
            powChart.Series[0].Points.Clear();
            powChart.Series[1].Points.Clear();

            this.Text = "SaRS InstruMan";
            fileopened = "";
        }

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (Settings.EmergencyStop)
            {
                if (keyData == (Keys.Control | Keys.Alt | Keys.Space))
                {
                    if (offBtn.Enabled)
                        offBtn_Click(this, EventArgs.Empty);
                    else
                    {
                        if (CVL!=null)
                        {
                            if (CVL.VoltPort.IsOpen)
                            {
                                CVL.WriteAndRead("SOUT1\r");
                                Thread.Sleep(50);
                            }
                        }
                    }
                    StatusBar newb = new StatusBar();
                    newb.Text = "Safety Stop Triggered!";
                    Label lbl = new Label();
                    lbl.Dock = DockStyle.Fill;
                    lbl.TextAlign = ContentAlignment.MiddleCenter;
                    lbl.Text = "Safety Stop Triggered!";
                    lbl.BackColor = Color.Red;
                    lbl.ForeColor = Color.White;
                    newb.Controls.Add(lbl);
                    newb.Dock = DockStyle.Bottom;
                    this.Controls.Add(newb);
                    this.Refresh();
                    Thread.Sleep(1000);
                    this.Controls.Remove(newb);
                    newb.Dispose();
                    newb = null;
                    lbl.Dispose();
                    lbl = null;
                    return true;
                }
            }
            return base.ProcessCmdKey(ref msg, keyData);
        }
        public void AutoSaveThread()
        {
            shouldstopautosave = false;
            while (shouldstopautosave == false)
            {
                Thread.Sleep(Settings.AutoSaveTimeout);
                AutoSave();
            }
        }

        public delegate void AutoSaveDel();

        private void toolStripButton7_Click_1(object sender, EventArgs e)
        {
            SettingsForm settingsform = new SettingsForm();
            settingsform.autosaveChk.Checked = Settings.AutoSave;
            settingsform.emkeyChk.Checked = Settings.EmergencyStop;
            settingsform.ShowDialog();
            if (settingsform.cancel == false)
            {
                Settings.AutoSave = settingsform.autosaveChk.Checked;
                Settings.EmergencyStop = settingsform.emkeyChk.Checked;
                if(autosavethread==null)
                {
                    if (settingsform.autosaveChk.Checked)
                    {
                        autosavethread = new Thread(new ThreadStart(this.AutoSaveThread));
                        autosavethread.Start();
                        while (!autosavethread.IsAlive) ;
                    }
                }
                else
                {
                    if (settingsform.autosaveChk.Checked && !autosavethread.IsAlive)
                    {
                        autosavethread.Start();
                        while (!autosavethread.IsAlive) ;
                    }
                    if (!settingsform.autosaveChk.Checked)
                    {
                        shouldstopautosave = true;
                        if (autosavethread.IsAlive)
                        {
                            autosavethread.Abort();
                        }
                        while (autosavethread.IsAlive) ;
                        autosavethread = null;
                    }
                }
            }
        }

        private void prjlistTree_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.F2)
            {
                prjlistTree.SelectedNode.BeginEdit();
            }
        }

        public void AutoSave()
        {
            if (this.prjlistTree.InvokeRequired)
            {
               AutoSaveDel d = new AutoSaveDel(AutoSave);
                Invoke(d, new object[] { });
            }
            else
            {
                if (fileopened!="")
                {
                    SaveFile(fileopened);
                }
            }
        }
    }
}
